# -*- coding: utf-8 -*-
import json

from django.utils.functional import SimpleLazyObject
from django.contrib.auth.models import AnonymousUser
from django.conf import settings

from common.log import logger
from .models import BkMiniWeixinUser, BkMiniWeiXinUserSession
from .accounts import MiniWeixinAccount


def get_user(request):
    user = None
    bktoken = request.META.get('HTTP_BKTOKEN')
    if bktoken:
        try:
            session = BkMiniWeiXinUserSession.objects.get(bktoken=bktoken)
            try:
                user = BkMiniWeixinUser.objects.get(openid=session.openid)
            except BkMiniWeixinUser.DoesNotExist:
                user = None
        except BkMiniWeiXinUserSession.DoesNotExist:
            user = None
    return user or AnonymousUser()


class MiniWeixinProxyPatchMiddleware(object):
    """
    该中间件需要被放置在所有中间件之前
    解决多级Nginx代理下原始来源Host(`X-Forwarded-Host`)被下层Nginx覆盖的问题
    解决方式：单独设置一个Header，本中间件进行覆盖替换`X-Forwarded-Host`

    # django 获取Host方式
    # django.http.request +73
    def get_host(self):
        '''Returns the HTTP host using the environment or request headers.'''
        # We try three options, in order of decreasing preference.
        if settings.USE_X_FORWARDED_HOST and (
                'HTTP_X_FORWARDED_HOST' in self.META):
            host = self.META['HTTP_X_FORWARDED_HOST']
            ...
    """
    def process_request(self, request):
        if settings.USE_MINIWEIXIN and settings.X_FORWARDED_MINIWEIXIN_HOST in request.META:
            # patch X-Forwaded-Host header
            request.META["HTTP_X_FORWARDED_HOST"] = request.META.get(settings.X_FORWARDED_MINIWEIXIN_HOST)


class MiniWeixinAuthenticationMiddleware(object):
    def process_request(self, request):
        setattr(request, 'miniweixin_user', SimpleLazyObject(lambda: get_user(request)))


class MiniWeixinLoginMiddleware(object):
    """mini weixin Login middleware."""

    def process_view(self, request, view, args, kwargs):
        """process_view."""
        miniweixin_account = MiniWeixinAccount()
        # 非微信小程序路径不验证
        if not miniweixin_account.is_miniweixin_visit(request):
            return None

        # 豁免微信小程序登录装饰器
        if getattr(view, 'miniweixin_login_exempt', False):
            return None

        # 验证OK
        if request.miniweixin_user.is_authenticated():
            return None

        # 微信登录失效或者未通过验证，直接重定向到微信登录
        return miniweixin_account.redirect_miniweixin_login(request)


class MiniWeixinRequestBodyJsonMiddleware(object):
    """处理微信请求（wx.request）默认数据类型为content-type=application/json的数据处理"""

    def process_request(self, request):
        # 非微信小程序路径不验证
        if not MiniWeixinAccount().is_miniweixin_visit(request):
            return None
        setattr(request, 'body_data', {})
        if request.META.get('CONTENT_TYPE', '').startswith('application/json') and request.body:
            try:
                request.body_data = json.loads(request.body.decode('utf-8'))
            except Exception as error:
                logger.exception(error)
                request.body_data = {}


class MiniWeixinCsrfExemptMiddleware(object):
    """对于微信小程序，无需校验csrftoken"""
    def process_request(self, request):
        # 非微信小程序路径不验证
        if not MiniWeixinAccount().is_miniweixin_visit(request):
            return None
        # 将csrftoken的校验设置为已经校验过了
        setattr(request, 'csrf_processing_done', True)
